package com.winit.common.util;

import com.winit.common.base.beans.FileBaseInfo;
import com.winit.common.base.beans.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 文档上传通用类
 * Created by wangjian on 16/9/22.
 */
public class FileUpload {

    private static final Logger logger = LoggerFactory.getLogger(FileUpload.class);

    /**
     * 上传文件,并生成描述文件
     * @param fileDir 上传文件保存路径(文件夹,不包括文件名)
     * @param source
     * @param fileInfo 描述文件bean,可扩展
     * @param user 登录用户信息
     * @param isCreateDir 当fileDir不存在时,是否自动创建该目录
     * @param isAddPrefix 是否在文件名中自动添加序号
     * @param isCoverOld 当上传文件同名时,是否覆盖旧文件 isAddPrefix为true时,不会出现该情况
     * @return
     * @throws Exception
     */
    public static boolean uploadFile(String fileDir, MultipartFile source
            ,FileBaseInfo fileInfo,LoginUser user
            ,boolean isCreateDir,boolean isAddPrefix,boolean isCoverOld) throws Exception{
        //上传的文件名 中文乱码
        String fileName = new String(source.getOriginalFilename().getBytes("iso-8859-1"),"utf-8");
        logger.info("上传文件,fileDir="+fileDir+",user="+user.getUserName()+",fileName="+fileName+",isCreateDir="
                +isCreateDir+",isAddPrefix="+isAddPrefix);
        File dirFile = new File(fileDir);
        if(!dirFile.exists()){
            if(!isCreateDir){
                logger.error("上传文件,文件保存目录不存在.fileDir="+fileDir);
                throw new Exception("上传文件,文件保存目录不存在.fileDir="+fileDir);
            }
            dirFile.mkdirs();
        }
        List<File> files = getFiles(fileDir);
        //文件名添加前缀
        if(isAddPrefix){
            String prefix = "001";
            if(files.size() > 0){
                for (int i = files.size()-1;i >= 0;i--){
                    String name = files.get(i).getName();
                    if(name.contains("_")){
                        try {
                            Integer count = Integer.parseInt(name.split("_")[0]);
                            prefix = getFilePrefix(count);
                            break;
                        }catch (Exception e){}
                    }
                }
            }
            fileName = prefix + "_" + fileName;
        }
        String filePath = fileDir + "/" + fileName;
        File file = new File(filePath);
        if(file.exists() && !isCoverOld){
            logger.error("上传文件,同名文件已存在.filePath="+filePath);
            throw new Exception("上传文件,同名文件已存在.filePath="+filePath);
        }
        byte[] bytes = source.getBytes();
        BufferedOutputStream stream = null;
        try {
            stream = new BufferedOutputStream(new FileOutputStream(filePath));
            stream.write(bytes);
            stream.close();

        } catch (IOException e) {
            throw e;
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
        //生成描述文件
        fileInfo.setFileName(fileName);
        fileInfo.setCreateDate(DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss"));
        fileInfo.setUploader(user.getUserName());
        JSONFileUtil.saveFileJson(filePath+".desc",fileInfo);
        return true;
    }

    /**
     * 获取指定目录下文件信息列表
     * @param fileDir
     * @return
     * @throws Exception
     */
    public static <T> List<T> getFileInfoList(String fileDir,Class<T> clazz) throws Exception {
        List<T> list = new ArrayList<>();
        List<File> files = getFiles(fileDir);
        for (File file:files){
            T info = JSONFileUtil.getFileJsonForBean(file.getAbsolutePath()+".desc",clazz);
            if(info != null){
                list.add(info);
            }
        }
        return list;
    }

    /**
     * 获取上传文件目录下文件列表
     * @param fileDir
     * @return
     */
    private static List<File> getFiles(String fileDir) throws Exception {
        List<File> list = new ArrayList<>();
        File file = new File(fileDir);
        if(!file.exists()){
            logger.warn("获取指定目录下文件列表,目录不存在.fileDir="+fileDir);
            return list;
        }
        for (File f : file.listFiles()){
            if(f.isDirectory()){
                continue;
            }
            //排除描述文件
            if(f.getName().endsWith(".desc")){
                continue;
            }
            list.add(f);
        }

        Collections.sort(list, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                String name1 = o1.getName();
                String name2 = o2.getName();
                return name1.compareTo(name2);
            }
        });
        return list;
    }

    /**
     * 根据当前最后一个文件的前缀生成下一个文件前缀
     * @param prefix
     * @return
     */
    private static String getFilePrefix(Integer prefix){
        String string = String.valueOf(prefix+1);
        int length = string.length();
        if(length == 1){
            string = "00"+string;
        }else if(length == 2){
            string = "0"+string;
        }
        return string;
    }

}
